package org.example.demo3.demos.web.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import org.example.demo3.demos.web.Mapper.UserMapper;
import org.example.demo3.demos.web.domain.vo.AddressVO;
import org.example.demo3.demos.web.domain.vo.UserVO;
import org.example.demo3.demos.web.entity.Address;
import org.example.demo3.demos.web.entity.User;
import org.example.demo3.demos.web.enums.UserStatus;
import org.example.demo3.demos.web.service.IAddressService;
import org.example.demo3.demos.web.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService{
    @Autowired
    private IAddressService iAddressService;
    @Override
    public void UserMinuteYuE(String id, int money) {
        // 1.查询用户
        User user = this.getById(id);
        // 2.校验状态
        if(user == null || user.getStatus() == UserStatus.FORZEN){ // 冻结不处理
            throw new RuntimeException("用户状态异常");
        }
        // 3.校验余额
        if(user.getPassword() <= money){ // 小于这个数就无法抵扣，给个报错
            throw new RuntimeException("用户余额不够");
        }

        // 4.扣减额度
//        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>(); // 自己写的，也可以使用。
//        userUpdateWrapper.eq("id",id);
//        userUpdateWrapper.setSql("password = password - 200");
//        this.update(userUpdateWrapper);
        baseMapper.MinuteYeSelf(id,money);
    }

    @Override
    public List<User> duoTiaoJianFn(String name, Integer status, Integer minPassword, Integer maxPassword) {
/*        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(name != null,User::getUsername,name)
                .eq(status != 2,User::getStatus,status)
                .lt(maxPassword != null,User::getPassword,maxPassword)
                .gt(minPassword != null,User::getPassword,minPassword);
        return this.list(userLambdaQueryWrapper); // 原本写法*/
        return lambdaQuery().like(name != null, User::getUsername, name)
                .eq(status != 2, User::getStatus, status)
                .lt(maxPassword != null, User::getPassword, maxPassword)
                .gt(minPassword != null, User::getPassword, minPassword)
//                .list() // 调用list方法，就是都是列表
//                .page() // 如果是分页的话，就直接调用page
//                .exists() // 只是校验是否存在，就级联调用这个方法
                .list();
    }

    @Override
    @Transactional // 加上事务， 一条失败，全部流程恢复。
    public List<User> lambdaUpdateSelf(String id, Integer money) {
        // 1. 查询用户
        User user = this.getById(id);
        // 2.查询用户状态
        if(user == null || user.getStatus() == UserStatus.FORZEN){
            throw new RuntimeException("不存在用户");
        }
        if(user.getPassword() < money){
            throw  new RuntimeException("余额不足");
        }

        int remind = user.getPassword() - money;
        lambdaUpdate()
                .set(User::getPassword,remind)
                .eq(User::getId,id) // 找到id指定值
                .set(remind <=0,User::getStatus,2) // 判断如果小于0 ，就将状态更改
//                .eq(User::getPassword,user.getPassword()) // 乐观锁，就是在执行前，再次判断值是否是自己上次查询的值，因为多线程有可能别人已经修改过值了。
                .update(); // 执行sql语句，一定要写

        return null;
    }

    @Override
    public UserVO queryUserAndAddress(String id) {
        User user = Db.getById(id,User.class); // 用户信息
        // 从address获取信息
        if(user == null || user.getStatus() == UserStatus.FORZEN){
            throw  new RuntimeException("状态有问题！");
        }
        UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);

        List<Address> addresses = iAddressService.list(new LambdaQueryWrapper<Address>().eq(Address::getUserId, id)) ;
//        List<Address> addresses = Db.lambdaQuery(Address.class).eq(Address::getUserId, id).list();
        if(CollUtil.isNotEmpty(addresses)){
            List<AddressVO> addressVOS = BeanUtil.copyToList(addresses, AddressVO.class);
            userVO.setAddresses(addressVOS);
        }

        return userVO;
    }


}

























